<template>
	<a-card :bordered="false" style="margin-bottom: 10px">
		<a-spin :spinning="spinning" :delay="delayTime">
			<!-- 统计 -->
			<div style="padding-bottom: 10px">
				<a-alert :message="statistics" :type="alertType" show-icon> </a-alert>
			</div>
			<s-table
				ref="table"
				:scroll="{ x: '1000px' | true }"
				:columns="importData.columns"
				:data="loadData"
				:expand-row-by-click="true"
				:alert="options.alert.show"
				bordered
				:row-key="(record) => record.id"
				:row-selection="options.rowSelection"
				:tool-config="toolConfig"
				:row-class-name="(record) => (record.hasError ? 'errorRow' : '')"
			>
				<template #operator>
					<a-space>
						<a-popconfirm title="确定要删除选中数据吗？" @confirm="deleteData">
							<a-button danger :disabled="selectedRowKeys.length === 0">
								<template #icon><delete-outlined /></template>删除</a-button
							>
						</a-popconfirm>
					</a-space>
				</template>
				<template #bodyCell="{ column, text, record }">
					<template v-if="column.dataIndex === 'action'">
						<div class="editable-row-operations">
							<span v-if="editableData[record.id]">
								<a-space>
									<a-typography-link @click="save(record.id)">保存</a-typography-link>
									<a-popconfirm title="确定要取消吗?" @confirm="cancel(record.id)">
										<a>取消</a>
									</a-popconfirm>
								</a-space>
							</span>
							<span v-else>
								<a-space>
									<a @click="edit(record.id)">编辑</a>
									<a-divider type="vertical" />
									<a-popconfirm title="确定要删除吗？" @confirm="onDelete(record.id)">
										<a-button type="link" danger size="small">删除</a-button>
									</a-popconfirm>
								</a-space>
							</span>
						</div>
					</template>
					<template v-else>
						<div>
							<a-input
								v-if="editableData[record.id]"
								v-model:value="editableData[record.id][column.dataIndex]"
								@keyup.enter="save(record.id)"
								style="margin: -5px 0"
							/>
							<!-- 如果是日期并且没有错误则格式化成年月日格式 -->
							<template v-else-if="column.date && record.errorInfo[column.dataIndex] == null">
								{{ text && text.substr(0, 10) }}
							</template>
							<!-- 如果是日期并且有错误 -->
							<!-- <template v-else-if="column.date && record.errorInfo[column.dataIndex] != null">
									{{ text || '输入有误' }}
								</template> -->
							<!--如果有错并且错误信息里有-->
							<template v-else-if="record.hasError && record.errorInfo[column.dataIndex] != null">
								<div class="editable-cell">
									<div class="editable-cell-input-wrapper">
										<a-typography-text type="danger">
											{{ text || '输入有误' }}
											<a-popover>
												<template #content>
													<p class="red">{{ record.errorInfo[column.dataIndex] }}</p>
												</template>
												<span class="editable-cell-icon-check">
													<slot name="icon">
														<question-circle-outlined />
													</slot>
												</span>
											</a-popover>
										</a-typography-text>
									</div>
								</div>
							</template>
							<template v-else>
								{{ text }}
							</template>
						</div>
					</template>
				</template>
			</s-table>
		</a-spin>
	</a-card>
</template>
<script setup name="ImportSubmit">
	import tool from '@/utils/tool'
	import { cloneDeep } from 'lodash-es'
	const spinning = ref(false) //加载中
	const delayTime = 100 //延迟显示加载效果的时间（防止闪烁）
	const table = ref() //表格
	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false } //表格工具配置
	const editableData = reactive({}) //编辑行数据
	const alertType = ref('success')
	//props
	const props = defineProps({
		//导入接口
		api: { type: Object },
		//单次最大导入数量
		maxUploadCount: { type: Number, default: 1000 }
	})
	const emit = defineEmits({ updateResult: null }) //emit
	//导入的数据
	const importData = reactive({
		hasError: true,
		//表头
		columns: [],
		//导入数据
		data: []
	})
	//统计数据
	const statistics = computed(() => {
		let errorCount = importData.data.filter((item) => item.hasError).length
		let message = `预计导入${importData.data.length}条数据`
		if (errorCount > 0) {
			alertType.value = 'warning'
			message = message + `,其中${errorCount}条数据可能有误,请按提示调整后再导入!`
		} else {
			importData.hasError = false
		}
		return message
	})

	//编辑行
	const edit = (id) => {
		editableData[id] = cloneDeep(importData.data.filter((item) => id === item.id)[0])
	}
	//保存行
	const save = (id) => {
		Object.assign(importData.data.filter((item) => id === item.id)[0], editableData[id])
		delete editableData[id]
	}
	//取消编辑行
	const cancel = (id) => {
		delete editableData[id]
	}
	//删除行
	const onDelete = (id) => {
		importData.data = importData.data.filter((item) => item.id !== id)
		selectedRowKeys.value.pop(id)
		tableRefresh()
	}
	//选择项
	let selectedRowKeys = ref([])
	// 列表选择配置
	const options = reactive({
		alert: {
			show: true, //显示选择多少个
			clear: () => {
				selectedRowKeys = ref([])
			}
		},
		rowSelection: {
			onChange: (selectedRowKey, selectedRows) => {
				selectedRowKeys.value = selectedRowKey
				//如果有选择就显示选择个数
				if (selectedRowKey.length > 0) {
					options.alert.show = true
				} else {
					options.alert.show = false
				}
			}
		}
	})
	//批量删除
	const deleteData = () => {
		importData.data = importData.data.filter((item) => !selectedRowKeys.value.includes(item.id))
		tableRefresh()
	}
	// 表格查询 返回 Promise 对象
	const loadData = (parameter) => {
		return dataPage(parameter)
	}
	//数据分页
	const dataPage = (parameter) => {
		return new Promise((resolve, reject) => {
			var data = tool.page(parameter, importData.data)
			resolve(data)
		})
	}

	// 打开页面
	const onOpen = (data) => {
		importData.hasError = data.hasError
		importData.data = data.data
		//动态表头赋值
		importData.columns = data.tableColumns
		importData.columns.push({
			title: '操作',
			dataIndex: 'action',
			align: 'center',
			fixed: 'right',
			width: '130px'
		})
		tableRefresh()
	}

	// 查看错误详情
	const onFail = (data) => {
		if (data) {
			importData.hasError = true
			importData.data = data
			spinning.value = false
			tableRefresh()
		}
	}

	// 验证并提交数据
	const onSubmit = () => {
		//否则直接全量提交
		spinning.value = true
		return dataImport(importData.data)
	}
	// 批量验证并提交数据
	const onSubmitBatch = () => {
		var hasErrorData = importData.data.filter((item) => item.hasError === true) //有错误的数据最后导入
		var noErrorData = importData.data.filter((item) => item.hasError === false) //没错误的数据
		dataImportBatch(noErrorData, 1) //先导入没有错的数据
		dataImportBatch(hasErrorData, 1) //再导入有错的数据
	}

	//批量导入数据
	const dataImportBatch = (importData, current) => {
		if (importData.length > 0) {
			let parameter = { size: props.maxUploadCount, current: current } //分页信息
			let data = tool.page(parameter, importData) //分页
			dataImport(data.records)
				.then((res) => {
					//如果导入成功
					emit('updateResult', res) //更新导入结果
					if (data.hasNextPages) {
						//如果有下一页就继续请求
						dataImportBatch(importData, current + 1)
					}
				})
				.catch((err) => {
					emit('updateResult', { importCount: 0, failCount: data.records.length, data: data.records }) //更新导入结果
				})
		}
	}

	//导入数据
	const dataImport = (data) => {
		return new Promise((resolve, reject) => {
			props.api
				.import({ data: data })
				.then((data) => {
					resolve(data)
				})
				.catch((err) => {
					reject(err)
				})
				.finally(() => {
					spinning.value = false
				})
		})
	}
	//刷新表格
	const tableRefresh = () => {
		// table.value.refresh(true)
		table.value.clearRefreshSelected()
	}
	//判断是否需要分批次导入
	function needBatch() {
		return importData.data.length > props.maxUploadCount
	}
	//获取导入数量
	function getImportCount() {
		return importData.data.length
	}
	// 调用这个函数将子组件的一些数据和方法暴露出去
	defineExpose({
		onOpen,
		onSubmit,
		onSubmitBatch,
		onFail,
		needBatch,
		getImportCount
	})
</script>

<style scoped lang="less">
	.red {
		color: red;
	}

	.spin {
		text-align: center;
		/* background: rgba(0, 0, 0, 0.05); */
		/* border-radius: 4px; */
		/* margin-bottom: 20px; */
		/* padding: 30px 50px; */
		margin: 300px 0;
	}

	.editable-row-operations a {
		margin-right: 8px;
	}

	.ant-table tr.changeRed {
		background: #ffdada;
	}

	.editable-cell {
		position: relative;

		.editable-cell-input-wrapper,
		.editable-cell-text-wrapper {
			padding-right: 24px;
		}

		.editable-cell-text-wrapper {
			padding: 5px 24px 5px 5px;
		}

		.editable-cell-icon,
		.editable-cell-icon-check {
			position: absolute;
			right: 0;
			width: 10px;

			cursor: pointer;
		}

		.editable-cell-icon {
			margin-top: 4px;
			display: none;
		}

		.editable-cell-icon-check {
			line-height: 24px;
		}

		// .editable-cell-icon:hover,
		// .editable-cell-icon-check:hover {
		// 	color: #f1e207;
		// }

		.editable-add-btn {
			margin-bottom: 8px;
		}
	}

	.editable-cell:hover .editable-cell-icon {
		display: inline-block;
	}
</style>
